package com.tanhua.admin.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.tanhua.admin.mapper.AnalysisMapper;
import com.tanhua.admin.mapper.LogMapper;
import com.tanhua.dubbo.api.UserApi;
import com.tanhua.model.domain.Analysis;
import com.tanhua.model.vo.GaiYaoVo;
import com.tanhua.model.vo.YearVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author 夯大力
 * 2021/11/8
 * 15:16
 */
@Service
public class DashboardService {
    @DubboReference
    private UserApi userApi;
    @Autowired
    private LogMapper logMapper;
    @Autowired
    private AnalysisMapper analysisMapper;

    /**
     * 展示后台用户的概要
     *
     * @return
     */
    public GaiYaoVo summary() {
        GaiYaoVo vo = new GaiYaoVo();
        //完善vo中的每一个属性
        //1,累计用户,在用户表中查询出所有的id数量即可
        Integer cumulativeUsers = userApi.getCount();
        vo.setCumulativeUsers(cumulativeUsers);
        //2,过去30天活跃用户
        DateTime dateTime = DateUtil.lastMonth();
        String month = DateUtil.format(dateTime, "yyyy-MM-dd");
        //今日时间
        String today = DateUtil.today();
        Integer activePassMonth = logMapper.monthCount(today, month);
        vo.setActivePassMonth(activePassMonth);
        //3,一周内活跃用户
        DateTime weekdateTime = DateUtil.lastWeek();
        String week = DateUtil.format(weekdateTime, "yyyy-MM-dd");
        Integer activePassWeek = logMapper.monthCount(today, week);
        vo.setActivePassWeek(activePassWeek);
        //4今日新增用户
        Integer newUsersToday = logMapper.queryByTypeAndLogTime("0102", today);
        vo.setNewUsersToday(newUsersToday);
        //5昨天的新增数量
        String yesterday = DateUtil.yesterday().toString("yyyy-MM-dd");
        Integer newUsersYesDay = logMapper.queryByTypeAndLogTime("0102", yesterday);
        Double newUsersTodayRate = HuanBi(newUsersToday, newUsersYesDay);

        vo.setNewUsersTodayRate(newUsersTodayRate);
        //6今日登录次数
        Integer loginTimesToday = logMapper.queryByTypeAndLogTime("0101", today);
        vo.setLoginTimesToday(loginTimesToday);
        //7昨日登录数量
        Integer loginTimesYesday = logMapper.queryByTypeAndLogTime("0101", yesterday);
        //环比
        Double loginTimesTodayRate = HuanBi(loginTimesToday, loginTimesYesday);
        vo.setLoginTimesTodayRate(loginTimesTodayRate);
        //8今日活跃数,
        Integer activeUsersToday = logMapper.queryByLogTime(today);
        vo.setActiveUsersToday(activeUsersToday);
        //活跃数环比
        Integer activeUsersYesday = logMapper.queryByLogTime(yesterday);

        Double activeUsersTodayRate = HuanBi(activeUsersToday, activeUsersYesday);
        vo.setActiveUsersTodayRate(activeUsersTodayRate);

        return vo;
    }

    /**
     * 得到2个数的环比值
     *
     * @param start
     * @param end
     * @return
     */
    private double HuanBi(Integer start, Integer end) {
        //得到环比的百分比
        if (end == 0) {
            end = 1;
        }
        BigDecimal div = NumberUtil.div(start, end);
        double i = div.doubleValue();
        if (i < 1) {
            i = -i;
        }
        return i * 100;
    }

    /**
     * @param sd   开始日期
     * @param ed   结束日期
     * @param type 类型
     * @return 101 新增 102 活跃用户 103 次日留存率
     */
    public Map<String, Object> users(String sd, String ed, String type) {
        DateTime sdate = DateUtil.date(Long.valueOf(sd));
        DateTime edate = DateUtil.date(Long.valueOf(ed));
        //格式转化

        //今年的用户数据
        ArrayList<YearVo> list1 = new ArrayList<>();
        //去年的数据
        ArrayList<YearVo> list2 = new ArrayList<>();
        //在sd和ed的区间内查询出每一天的数据
        HashMap<String, Object> map = new HashMap<>();
        //查询出今年的数据

        cmoMethod(type, sdate, edate, list1);

        //查询出去年同期的数据
        DateTime sdateTime = DateUtil.offsetMonth(sdate, -12);
        DateTime edateTime = DateUtil.offsetMonth(edate, -12);
        cmoMethod(type, sdateTime, edateTime, list2);


        map.put("thisYear", list1);
        map.put("lastYear", list2);
        return map;
    }


    /**
     * 公共方法将查询出来的每一天的数据放入到集合中
     * @param type
     * @param sdate
     * @param edate
     * @param list1
     */
    private void cmoMethod(String type, DateTime sdate, DateTime edate, ArrayList<YearVo> list1) {
        String s = sdate.toString("yyyy-MM-dd");
        String e = edate.toString("yyyy-MM-dd");
        if ("101".equals(type)) {
            List<Analysis> voList = analysisMapper.getDay(s, e);
            common(list1, voList);
        } else if ("102".equals(type)) {
            List<Analysis> voList = analysisMapper.getDay(s, e);
            common2(list1, voList);
        } else {
            //今天的留存数
            List<Analysis> voList = analysisMapper.getDay(s, e);
            String s2 = DateUtil.offsetDay(sdate, -1).toString("yyyy-MM-dd");
            String e2 = DateUtil.offsetDay(edate, -1).toString("yyyy-MM-dd");
            //昨日的新增数
            List<Analysis> voList2 = analysisMapper.getDay(s2, e2);
            Map<Date, Analysis> valueMap = CollUtil.fieldValueMap(voList2, "recordDate");
            for (Analysis anal : voList) {
                //10号的留存用户应该与9号的新增用户去比较
                Date recordDate = anal.getRecordDate();
                DateTime dateTime = DateUtil.offsetDay(recordDate, -1);
                Analysis analysis = valueMap.get(dateTime);
                if (analysis != null) {
                    YearVo vo = new YearVo();
                    vo.setTitle(DateUtil.format(recordDate, "yyyy-MM-dd"));
                    //10号的留存数
                    Integer liuCun = anal.getNumRetention1d();
                    //9号的新增数
                    Integer zhuChe = analysis.getNumActive();
                    if (zhuChe == null || zhuChe == 0) {
                        zhuChe = 1;
                    }
                    BigDecimal div = NumberUtil.div(liuCun, zhuChe);
                    double i = div.doubleValue();
                    vo.setAmount(i * 100);
                    list1.add(vo);
                }

            }
        }
    }

    /**
     * 往集合中放入每日新增用户数
     * @param list1
     * @param voList
     */
    private void common(ArrayList<YearVo> list1, List<Analysis> voList) {
        for (Analysis anal : voList) {
            YearVo vo = new YearVo();

            String format = DateUtil.format(anal.getRecordDate(), "yyyy-MM-dd");
            vo.setTitle(format);
            vo.setAmount((double)anal.getNumRegistered());
            list1.add(vo);
        }
    }

    /**
     * 往集合中放入每日活跃用户数
     * @param list1
     * @param voList
     */
    private void common2(ArrayList<YearVo> list1, List<Analysis> voList) {
        for (Analysis anal : voList) {
            YearVo vo = new YearVo();

            String format = DateUtil.format(anal.getRecordDate(), "yyyy-MM-dd");
            vo.setTitle(format);
            vo.setAmount((double)anal.getNumActive());
            list1.add(vo);
        }
    }
}
